import { NestFactory, Reflector } from '@nestjs/core';
import { AppModule } from './app.module';
import { AllExceptionsFilter } from './middleware/any-exception.filter';
import { TransformInterceptor } from './middleware/transform.interceptor';
import { setupSwagger } from './setup-swagger';
import helmet from 'helmet';
import {
  ExpressAdapter,
  NestExpressApplication,
} from '@nestjs/platform-express';
import {
  initializeTransactionalContext,
  patchTypeORMRepositoryWithBaseRepository,
} from 'typeorm-transactional-cls-hooked';
// import helmet from 'helmet';
import RateLimit from 'express-rate-limit';
declare const module: any;
export async function bootstrap(): Promise<NestExpressApplication> {
  initializeTransactionalContext();
  patchTypeORMRepositoryWithBaseRepository();
  const app = await NestFactory.create<NestExpressApplication>(
    AppModule,
    new ExpressAdapter(),
    { cors: true },
  );
  app.useGlobalInterceptors(new TransformInterceptor());
  app.enable('trust proxy'); // only if you're behind a reverse proxy (Heroku, Bluemix, AWS ELB, Nginx, etc)
  app.use(helmet());
  
  app.use(
    RateLimit({
      windowMs: 15 * 60 * 1000, // 15 minutes
      max: 100, // limit each IP to 100 requests per windowMs
    }),
  );
  // app.use(compression());
  // app.use(morgan('combined'));
  app.enableVersioning();

  const reflector = app.get(Reflector);

  // app.useGlobalFilters(
  //   new HttpExceptionFilter(reflector),
  //   new QueryFailedFilter(reflector),
  // );

  // app.useGlobalInterceptors(new ClassSerializerInterceptor(reflector));

  // app.useGlobalPipes(
  //   new ValidationPipe({
  //     whitelist: true,
  //     errorHttpStatusCode: HttpStatus.UNPROCESSABLE_ENTITY,
  //     transform: true,
  //     dismissDefaultMessages: true,
  //     exceptionFactory: (errors) => new UnprocessableEntityException(errors),
  //   }),
  // );

  // const configService = app.select(SharedModule).get(ApiConfigService);

  // only start nats if it is enabled
  // if (configService.natsEnabled) {
  //   const natsConfig = configService.natsConfig;
  //   app.connectMicroservice({
  //     transport: Transport.NATS,
  //     options: {
  //       url: `nats://${natsConfig.host}:${natsConfig.port}`,
  //       queue: 'main_service',
  //     },
  //   });

  //   await app.startAllMicroservices();
  // }

  // if (configService.documentationEnabled) {
    setupSwagger(app);
  // }

  // const port = configService.appConfig.port;
  // await app.listen(port);
  await app.listen(3000);
  // console.info(`server running on port ${port}`);
  // app.use(compression());
  if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => app.close());
  }
  return app;
}

void bootstrap();
